<template>
  <view>
    <!-- 收货地址列表 -->
    <view class="scroll-main">
      <scroll-view :scroll-y="true" @scrolltolower="loadMore" :style="{height: (windowHeight - 44 - 50) + 'px'}">
        <view class="list">
          <view class="item" v-for="(addrItem, addrIdx) in state.list" :key="addrIdx">
            <view class="top">
              <uni-tag class="address-icon" type="primary" v-if="addrItem.label" :text="mapLabel(addrItem.label)"></uni-tag>
              <text class="area-top">{{ assembleAddress(addrItem) }}</text>
            </view>
            <view class="middle">
              <view class="detail">
                <text>{{ addrItem.detail }}</text>
              </view>
              <view class="icon">
                <uni-icons type="compose" @click="showPopupForEdit(addrItem.id)"></uni-icons>
              </view>
            </view>
            <view class="bottom">
              <text class="receiver">{{ addrItem.addressee }}</text>
              <text class="phone">{{ addrItem.phone }}</text>
            </view>
          </view>
        </view>
        <uni-load-more :status="state.auxiliary.load.status"></uni-load-more>
      </scroll-view>
    </view>
    <view class="bottom-btn">
      <view class="btn-item">
        <button @tap="showPopupForAdd" type="warn" size="mini">新建地址</button>
      </view>
    </view>
    <!-- 弹窗表单 -->
    <uni-popup ref="addressPopupRef" type="bottom" border-radius="10px 10px 0 0">
      <view class="address-form" ref="viewRef">
        <uni-forms ref="formRef" :modelValue="state.addressForm" :rules="state.auxiliary.rules" label-width="80px">
          <uni-forms-item label="收货人" name="addressee" required>
            <uni-easyinput v-model="state.addressForm.addressee" placeholder="请输入姓名"/>
          </uni-forms-item>
          <uni-forms-item label="联系方式" name="phone" required>
            <uni-easyinput v-model="state.addressForm.phone" placeholder="请输入年龄"/>
          </uni-forms-item>
          <uni-forms-item label="所在地区" name="area" required>
            <uni-data-picker
                placeholder="请选择所在地区" popup-title="请选择所在地区"
                :localdata="state.auxiliary.regionTreeNodes" v-model="state.auxiliary.regionModel"
                @change="regionSelectDone"
            >
            </uni-data-picker>
          </uni-forms-item>
          <uni-forms-item label="详细地址" name="detail" required>
            <uni-easyinput v-model="state.addressForm.detail" placeholder="精确到门牌号"/>
          </uni-forms-item>
          <uni-forms-item label="标签" class="form-item">
            <uni-data-checkbox v-model="state.addressForm.label"
                               :localdata="state.auxiliary.labelList"></uni-data-checkbox>
          </uni-forms-item>
        </uni-forms>
        <view class="btn-grp">
          <button class="btn-item" type="primary" size="mini" @click="submit">提交</button>
          <button class="btn-item" size="mini" @click="cancel">取消</button>
        </view>
      </view>
    </uni-popup>
  </view>
</template>
<script setup lang="ts">
import {nextTick, ref} from "vue";
import type {AddressFormType, AddressItemType} from "@/types/user";
import {assembleAddress} from "@/utils/str";
import type {PageQueryType} from "@/types/global";
import {addAddress, editAddress, getAddress, getAddressListData} from "@/services/address";
import {onLoad} from "@dcloudio/uni-app";

const {windowHeight} = uni.getSystemInfoSync()

const formRef = ref()
const addressPopupRef = ref()
const viewRef = ref()
const state = ref({
  list: [] as Array<AddressItemType>,
  addressForm: {
    id: 0,
    addressee: "张三",
    phone: "1896693689",
    province: "浙江省",
    city: "杭州市",
    area: "西湖区",
    detail: "通天河9段",
    label: "WORK"
  } as AddressFormType,
  auxiliary: {
    regionTreeNodes: [
      {
        text: "浙江省", value: "浙江省",
        children: [
          {
            text: "杭州市", value: "杭州市",
            children: [
              {text: "西湖区", value: "西湖区"},
              {text: "余杭区", value: "西湖区"},
            ]
          },
          {
            text: "宁波市", value: "宁波市",
            children: [
              {text: "西湖区", value: "西湖区"},
              {text: "余杭区", value: "西湖区"},
            ]
          },
        ]
      },
      {
        text: "安徽省", value: "安徽省",
        children: [
          {text: "合肥市", value: "合肥市"},
          {text: "阜阳市", value: "阜阳市"},
        ]
      },
    ],
    regionModel: "西湖区",
    labelList: [
      {text: "家", value: "HOME"},
      {text: "公司", value: "WORK"},
    ],
    rules: {
      addressee: {
        rules: [
          {required: true, errorMessage: "收货人不能为空"},
          {minLength: 1, errorMessage: "请填入正确的收件人"}
        ]
      },
      phone: {
        rules: [{required: true, errorMessage: "联系方式不能为空"}]
      },
      area: {
        rules: [
          {required: true, errorMessage: "所在地区不能为空"},
          {
            // 如果使用了 validateFunction 且 required 为 false的情况，表现为不填写内容不校验，有内容才校验，
            // 所以内容为空时 validateFunction 不会执行 !!! 内容为空的时候由 required: true 校验
            validateFunction: (rule: any, value: any, data: any, callback: any) => {
              console.log("custom validate data: ", value, data, state.value.addressForm)
              if (state.value.addressForm.province.length <= 0) {
                callback('请选中正确的地区')
              }
              if (state.value.addressForm.city.length <= 0) {
                callback('请选中正确的地区')
              }
              if (state.value.addressForm.area.length <= 0) {
                callback('请选中正确的地区')
              }
              return true
            }
          }
        ]
      },
      // area: {
      //   rules: [{required: true, errorMessage: "所在地区不能为空"}]
      // },
      detail: {
        rules: [{required: true, errorMessage: "详细地址不能为空"}]
      }
    },
    query: {
      page: {
        page: 1,
        size: 10,
        orders: []
      } as PageQueryType
    },
    load: {
      status: "more",
      finish: false
    }
  }
})
const addressFormRef = ref()
const showPopupForEdit = (id: number) => {
  showPopupForm(id)
  uni.showToast({
    title: "编辑地址 " + id,
    icon: "none"
  })
}

const showPopupForAdd = () => {
  console.log("show popup ref: ", addressPopupRef.value, addressFormRef.value)
  showPopupForm(0)

}

const showPopupForm = async (id: number) => {
  if (id !== 0) {
    // 动态从接口获取要编辑的数据
    console.log("will request api to get edit data ", id)
    getAddress(id).then((r) => {
      if (r.code === 0) {
        state.value.addressForm = r.data
      }
    }).catch(() => {})
  }
  addressPopupRef.value.open()
  // 等待dom更新完成后再调用 否则会提示 form的ref不存在
  await nextTick()
  humanSetRules()
}

const closePopupForm = () => {
  addressPopupRef.value.close()
}

const mapLabel = (enLabel: string) => {
  for (let i = 0; i< state.value.auxiliary.labelList.length; i++) {
    if (state.value.auxiliary.labelList[i].value === enLabel) {
      return state.value.auxiliary.labelList[i].text
    }
  }
  return ""
}

/**
 * 完成选择地区时这里会返回每个节点选择的值
 * @param e
 */
const regionSelectDone = (e: any) => {
  console.log("after select region: ", e)
  state.value.addressForm.province = e.detail.value[0].value
  state.value.addressForm.city = e.detail.value[1].value
  state.value.addressForm.area = e.detail.value[2].value
}
const refreshList = () => {
  state.value.list = []
  state.value.auxiliary.query.page.page = 1
  loadAddressList()
}
/**
 * 加载收货地址列表
 */
const loadAddressList = () => {
  state.value.auxiliary.load.status = "loading"
  getAddressListData(state.value.auxiliary.query.page).then((r) => {
    if (r.code === 0) {
      state.value.list.push(...r.data.list)
      if (state.value.auxiliary.query.page.page >= r.data.pages) {
        state.value.auxiliary.load.status = "no-more"
        state.value.auxiliary.load.finish = true
      } else {
        state.value.auxiliary.load.status = "more"
      }
    } else {
      uni.showToast({
        title: r.msg,
        icon: "none"
      })
    }
  }).catch(() => {
    state.value.auxiliary.load.status = "no-more"
  })
}
/**
 * 加载下一页
 */
const loadMore = () => {
  if (state.value.auxiliary.load.finish) {
    return
  }
  state.value.auxiliary.query.page.page += 1
  loadAddressList()
}
const cancel = () => {
  closePopupForm()
}

const submit = () => {
  formRef.value.validate().then((res: any) => {
    console.log('表单数据信息：', res);
    uni.showToast({
      title: JSON.stringify(state.value.addressForm),
      icon: "none"
    })
    if (state.value.addressForm.id) {
      // 编辑
      editAddress(state.value.addressForm).then((r) => {
        if (r.code === 0) {
          uni.showToast({
            title: "修改成功",
            icon: "none"
          })
          closePopupForm()
          refreshList()
        }
      }).catch(() => {})
    } else {
      // 新增
    }
    addAddress(state.value.addressForm).then((r) => {
      if (r.code === 0) {
        uni.showToast({
          title: "添加成功",
          icon: "none"
        })
        closePopupForm()
        refreshList()
      }
    }).catch(() => {})
  }).catch((err: any) => {
    console.log('表单错误信息：', err);
  })
}

const humanSetRules = () => {
  formRef.value.setRules(state.value.auxiliary.rules)
  console.log("human set form rules")
}

onLoad(() => {
  loadAddressList()
})
</script>
<style lang="scss">
.scroll-main {
  background-color: #fff;

  .list {
    .item {
      padding: 10px 20px;
      border-bottom: 1px solid #ededed;

      .top {
        .address-icon {
          margin-right: 10px;
        }

        .area-top {
          color: #909399;
          font-size: 14px;
        }
      }

      .middle {
        margin-top: 10px;
        font-weight: bold;
        font-size: 16px;
        display: flex;
        justify-content: space-between;
      }

      .bottom {
        margin-top: 10px;
        color: #909399;
        font-size: 14px;

        .phone {
          margin-left: 10px;
        }
      }
    }
  }
}

.bottom-btn {
  background-color: #fff;
  padding-right: 20px;
  height: 50px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

.address-form {
  background-color: #fff;
  min-height: 300px;
  padding: 10px 20px;
}
.form-item {
  display: flex;
  align-items: center;
}
.btn-grp{
  display: flex;
  justify-content: center;
  border-top: 1px solid #ededed;
  padding-top: 20px;
  .btn-item {
  }
}
</style>